package com.lbd.email.service.impl;

import com.lbd.base.service.BaseServiceImpl;
import com.lbd.email.bean.EmailLog;
import com.lbd.email.bean.EmailTemplate;
import com.lbd.email.dao.EmailLogRepository;
import com.lbd.email.dao.EmailTemplateRepository;
import com.lbd.email.service.EmailTemplateService;
import com.lbd.system.bean.User;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.VelocityEngine;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.mail.internet.MimeMessage;
import java.io.StringWriter;
import java.util.Date;
import java.util.Map;

/**
 * Created by wang on 2016/9/23.
 */
@Service
@Transactional
public class EmailTemplateServiceImpl extends BaseServiceImpl<EmailTemplate, EmailTemplateRepository> implements EmailTemplateService {

    private final Logger log = Logger.getLogger(this.getClass());

    @Value("${spring.mail.username}")
    private String from;
    @Autowired
    EmailTemplateRepository emailTemplateRepository;
    @Autowired
    JavaMailSender javaMailSender;
    @Autowired
    EmailLogRepository emailLogRepository;
    @Autowired
    VelocityEngine velocityEngine;

    /**
     * 构建短信模板信息的查询条件和参数
     *
     * @param emailTemplate
     * @param parameter
     * @return
     */
    @Override
    public String buildJpql(EmailTemplate emailTemplate, Map<String, Object> parameter) {
        StringBuilder jpqlBuilder = new StringBuilder("  from  EmailTemplate t   ");
        if (emailTemplate != null) {
            if (StringUtils.isNotBlank(emailTemplate.getCode())) {
                jpqlBuilder.append(" and  code = :code");
                parameter.put("code", emailTemplate.getCode());
            }
        }
        jpqlBuilder.append(" order by code ");
        return jpqlBuilder.toString();
    }

    /**
     * 根据ID查询短信模板信息
     *
     * @param id
     * @return
     */
    @Override
    public EmailTemplate findById(String id) {
        return emailTemplateRepository.findOne(id);
    }


    /**
     * 发送邮件消息
     *
     * @param user 接收者
     * @param code key
     * @param data value
     */
    @Override
    public void sendEmail(User user, String code, Map<String, Object> data) {
        String content = "";
        // 记录日志
        EmailLog emailLog = new EmailLog();
        try {
            MimeMessage message = javaMailSender.createMimeMessage();
            // true表示需要创建一个multipart message
            MimeMessageHelper helper = new MimeMessageHelper(message, true);
            EmailTemplate template = emailTemplateRepository.findByCode(code);
            helper.setFrom(from);// 发送者
            helper.setTo(user.getEmail());// 接收者
            helper.setSubject(template.getSubject());// 邮件主题
            content = parseTemplate(template.getContent(), data);
            helper.setText(content, true);// 邮件内容
            helper.setSentDate(new Date());

            javaMailSender.send(message);
        } catch (Exception e) {
            log.warn("邮件发送异常", e);
            emailLog.setContent(e.getMessage());
            emailLog.setState(0);
        } finally {
            emailLog.setState(1);
            emailLog.setContent(content);
            emailLog.setContent(user.getEmail());
            addLog(emailLog);
        }
    }

    /**
     * 根据模板生成邮件数据
     *
     * @param templateContent
     * @param data
     * @return
     */
    private String parseTemplate(String templateContent, Map<String, Object> data) {
        VelocityContext context = new VelocityContext();
        for (String key : data.keySet()) {
            context.put(key, data.get(key));
        }
        StringWriter writer = new StringWriter();
        velocityEngine.evaluate(context, writer, "", templateContent);
        return writer.toString();
    }

    /**
     * 记录日志
     *
     * @param log 日志
     */
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public void addLog(EmailLog log) {
        emailLogRepository.save(log);
    }
}
